package fileoutputobjects;

import guiobjects.Observation;

import java.util.Random;


/**
 * This is the superclass of the simulators.
 * 
 * @author Trevor Terris
 *
 */
public abstract class HumanSimulator
{
    protected Random myRandom;
    protected double myXCoord, myZCoord;
    protected int myID;
    protected double[] myAttributes;
    
    //These values determine various aspects of the Simulators.
    //TODO: set these values
    protected double myMaxXValue = 1.0;
    protected double myMaxZValue = 1.0;
    protected double myMinXValue = 0.0;
    protected double myMinZValue = 0.0;
    protected int myNumAttributes = Observation.numAttributes;
    
    protected void setRandom(Random r)
    {
    	myRandom = r;
    }
    
    /**
     * A method that would presumably be used frequently. It repositions the simulator at a 
     * random position within the bounds specified by the myMax and myMin values above.
     */
    protected void setNewPositions()
    {
        myXCoord = myRandom.nextDouble() * (myMaxXValue - myMinXValue) + myMinXValue;
        myZCoord = myRandom.nextDouble() * (myMaxZValue - myMinZValue) + myMinZValue;
        randomizeAttributes();
    }
    
    protected void randomizeAttributes()
    {
        myAttributes = new double[myNumAttributes];
        for (int k = 0; k < myNumAttributes; k++)
        {
            myAttributes[k] = myRandom.nextDouble();
        } 
    }
    
    public int numAttributes()
    {
        return myNumAttributes;
    }
    
    public double getAttribute(int n)
    {
        return myAttributes[n];
    }
    
    /**
     * Returns the X coordinate of the object.
     * 
     * @return
     */
    public double trueXCoord()
    {
        return myXCoord;
    }
    
    /**
     * Returns the Z coordinate of the object.
     * 
     * @return
     */
    public double trueZCoord()
    {
        return myZCoord;
    }
    
    /**
     * Returns the ground-truth ID of the object.
     * 
     * @return
     */
    public int ID()
    {
        return myID;
    }
    
    /**
     * A method that would presumably be used frequently. Returns true if the object is within the bounds.
     * 
     * @return
     */
    protected boolean isInBounds()
    {
        return (myXCoord <= myMaxXValue && myZCoord <= myMaxZValue && myXCoord >= myMinXValue && myZCoord >= myMinZValue);
    }
    
    /**
     * This method changes the X coordinate and Z coordinate of the simulator. How exactly the value is changed depends 
     * on the kind of simulator.
     */
    public abstract void step();
}
